package com.jeecms.common.office;
/**
 * @author Tom
 */

import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
import com.jeecms.common.upload.UploadUtils;
import com.jeecms.common.util.SystemUtil;
import com.jeecms.common.web.Constants;
import com.jeecms.core.entity.CmsConfig;
import com.sun.star.awt.Size;
import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.XComponent;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.view.PaperFormat;
import com.sun.star.view.XPrintable;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class OpenOfficeConverter extends OpenOfficeDocumentConverter {
	private static final Logger log = LoggerFactory.getLogger(OpenOfficeConverter.class);

	public void startService() {
		DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
		try {
			log.info("准备启动OpenOffice服务....");
			configuration.setOfficeHome(getOfficeHome());// 设置OpenOffice.org安装目录
			configuration.setPortNumber(getPort()); // 设置转换端口，默认为8100
			configuration.setTaskExecutionTimeout(1000 * 60 * 5L);// 设置任务执行超时为5分钟
			configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);// 设置任务队列超时为24小时

			officeManager = configuration.buildOfficeManager();
			officeManager.start(); // 启动服务
			log.info("office转换服务启动成功!");
		} catch (Exception ce) {
			ce.printStackTrace();
			log.debug("office转换服务启动失败!详细信息:" + ce.getMessage());
		}
	}

	public void stopService() {
		log.info("关闭office转换服务....");
		if (officeManager != null) {
			officeManager.stop();
		}
		log.info("关闭office转换成功!");
	}

	/**
	 * 转换格式
	 * 
	 * @param inputFile
	 *            需要转换的原文件路径
	 * @param fileType
	 *            要转换的目标文件类型 html,pdf
	 */
	public File convert(String inputFile, String outPath, String fileType) {
		String outputFile = UploadUtils.generateFilename(outPath, fileType);
		if (inputFile.endsWith(".txt")) {
			String odtFile = FileUtils.getFilePrefix(inputFile) + ".odt";
			if (new File(odtFile).exists()) {
				log.info("odt文件已存在！");
				inputFile = odtFile;
			} else {
				try {
					FileUtils.copyFile(inputFile, odtFile);
					inputFile = odtFile;
				} catch (FileNotFoundException e) {
					log.info("文档不存在！");
					e.printStackTrace();
				}
			}
		}
		OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
		File output = new File(outputFile);
		converter.convert(new File(inputFile), output);
		return output;
	}

	/**
	 * 转换格式
	 * 
	 * @param inputFile
	 *            需要转换的原文件路径
	 * @param fileType
	 *            要转换的目标文件类型 html,pdf
	 */
	public File convert(String inputFile, String fileType, boolean delOldFile) {
		String outputFile = UploadUtils.generateFilename(getFilePath(), fileType);
		if (inputFile.toLowerCase().endsWith(".txt")) {
			String odtFile = FileUtils.getFilePrefix(inputFile) + ".odt";
			if (new File(odtFile).exists()) {
				log.info("该odt文件已存在！");
				inputFile = odtFile;
			} else {
				try {
					FileUtils.copyFile(inputFile, odtFile);
					inputFile = odtFile;
				} catch (FileNotFoundException e) {
					log.info("文档不存在！");
					e.printStackTrace();
				}
			}
		}
		OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
		File output = new File(outputFile);
		File oldFile = new File(inputFile);
		converter.convert(oldFile, output);
		if (delOldFile && oldFile.exists()) {
			oldFile.delete();
		}
		return output;
	}

	public File convertToPdf(String inputFile) throws Exception{
        String outputFile = inputFile.substring(0, inputFile.lastIndexOf("."));
		outputFile = UploadUtils.generateByFilename(outputFile, "", PDF);
		File tempFile = null;
        if (inputFile.endsWith(".pdf")) {
            return new File(outputFile);
        }
		if (inputFile.endsWith(".txt")) {
			String filecode = "";
			filecode=ConverEncoding.getFilecharset(inputFile);
			if (SystemUtil.isOSLinux()) {
				if (!filecode.equals(Constants.UTF8)) {
					try {
						Process process = Runtime.getRuntime()
								.exec("iconv -f " + filecode + "  -t utf-8 " + inputFile + " -c -s -o " + inputFile);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			} else {
				//UTF8编码的文本不需要转odt格式
				if (!filecode.equals(Constants.UTF8)) {
					String odtFile = FileUtils.getFilePrefix(inputFile) + ".odt";
					tempFile = new File(odtFile);
					if (tempFile.exists()) {
						inputFile = odtFile;
					} else {
						try {
							FileUtils.copyFile(inputFile, odtFile);
							tempFile = new File(odtFile);
							inputFile = odtFile;
						} catch (FileNotFoundException e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
		File output = new File(outputFile);
		converter.convert(new File(inputFile), output);
		if (tempFile != null && tempFile.exists()) {
			 tempFile.delete();
		}
		return output;
	}

	public void init(CmsConfig config) {
        OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1",8100);
		OpenOfficeConverter coverter = new OpenOfficeConverter(connection, config.getOfficeHome(), config.getOfficePort());
		coverter.startService();
		this.openOfficeConverter = coverter;
	}

	public void destroy() {
		this.openOfficeConverter.stopService();
	}

	public static void main(String[] args) {
		OpenOfficeConverter cov = new OpenOfficeConverter(null);
		Long s1 = System.currentTimeMillis();
		try {
			cov.startService();
		} catch (Exception e) {
			e.printStackTrace();
		}
		log.info("启动消耗时间+" + (System.currentTimeMillis() - s1) / 1000.0);

		OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
		File output = new File("D:/Workspace/jeecmsv9.2-src/target/jeecmsv9f/wenku/www/201801/34443.pdf");
		String inputFile = "D:/Workspace/jeecmsv9.2-src/target/jeecmsv9f/wenku/www/201801/30004953pk7m.pptx";
		if (inputFile.endsWith(".txt")) {
			String odtFile = FileUtils.getFilePrefix(inputFile) + ".odt";
			if (new File(odtFile).exists()) {
				log.info("odt文件已存在！");
				inputFile = odtFile;
			} else {
				try {
					FileUtils.copyFile(inputFile, odtFile);
					inputFile = odtFile;
				} catch (FileNotFoundException e) {
					log.info("文档不存在！");
					e.printStackTrace();
				}
			}
		}
		converter.convert(new File(inputFile), output);

		log.info("转换消耗时间" + (System.currentTimeMillis() - s1) / 1000.0);
		cov.stopService();
		log.info("停止消耗时间" + (System.currentTimeMillis() - s1) / 1000.0);
	}

	@Autowired
	private OpenOfficeConverter openOfficeConverter;
	private static OfficeManager officeManager;
	public static final String HTML = "html";
	public static final String PDF = "pdf";
	public static final String TXT = "txt";
	public static final String DOC = "doc";
	public static final String DOCX = "docx";
	public static final String XLS = "xls";
	public static final String XLSX = "xlsx";
	public static final String PPT = "ppt";
	public static final String PPTX = "pptx";
	public static final String WPS = "wps";
	private String officeHome = "D:/Program Files/OpenOffice 4";
	private int port = 8100;
	private String filePath;

    private final static Size A5, A4, A3;
    private final static Size B4, B5, B6;
    private final static Size KaoqinReport;

    static {
        A5 = new Size(14800, 21000);
        A4 = new Size(21000, 29700);
        A3 = new Size(29700, 42000);

        B4 = new Size(25000, 35300);
        B5 = new Size(17600, 25000);
        B6 = new Size(12500, 17600);

        KaoqinReport = new Size(29700, 27940);  //最大限度  宽 1600000
    }

    public OpenOfficeConverter(OpenOfficeConnection connection) {
        super(connection);
    }

    public OpenOfficeConverter(OpenOfficeConnection connection, String officeHome, int port) {
        super(connection);
        this.officeHome = officeHome;
        this.port = port;
    }

    @Override
    protected void refreshDocument(XComponent document) {
        super.refreshDocument(document);

        // The default paper format and orientation is A4 and portrait. To
        // change paper orientation
        // re set page size
        XPrintable xPrintable = UnoRuntime.queryInterface(XPrintable.class, document);
        PropertyValue[] printerDesc = new PropertyValue[2];

        // Paper Orientation
        //  printerDesc[0] = new PropertyValue();
        //  printerDesc[0].Name = "PaperOrientation";
        //  printerDesc[0].Value = PaperOrientation.PORTRAIT;

        // Paper Format
        printerDesc[0] = new PropertyValue();
        printerDesc[0].Name = "PaperFormat";
        printerDesc[0].Value = PaperFormat.USER;

        // Paper Size
        printerDesc[1] = new PropertyValue();
        printerDesc[1].Name = "PaperSize";
        printerDesc[1].Value = KaoqinReport;

        try {
            xPrintable.setPrinter(printerDesc);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public OpenOfficeConverter getOpenOfficeConverter() {
		return openOfficeConverter;
	}

	public void setOpenOfficeConverter(OpenOfficeConverter openOfficeConverter) {
		this.openOfficeConverter = openOfficeConverter;
	}

	public String getOfficeHome() {
		return officeHome;
	}

	public void setOfficeHome(String officeHome) {
		this.officeHome = officeHome;
	}

	public int getPort() {
		return port;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String filePath) {
		this.filePath = filePath;
	}

}
